﻿// 天才的记忆.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>


using namespace std;


/*

http://ybt.ssoier.cn:8088/problem_show.php?pid=1544

https://loj.ac/p/10122


原题来自：Vijos P1512

从前有个人名叫 W and N and B，他有着天才般的记忆力，他珍藏了许多许多的宝藏。
在他离世之后留给后人一个难题（专门考验记忆力的啊！），如果谁能轻松回答出这个问题，便可以继承他的宝藏。

题目是这样的：给你一大串数字（编号为 1 到 N，大小可不一定哦！），在你看过一遍之后，它便消失在你面前，随后问题就出现了，给你 M 个询问，
每次询问就给你两个数字 A,B，要求你瞬间就说出属于 A 到 B 这段区间内的最大数。

一天，一位美丽的姐姐从天上飞过，看到这个问题，感到很有意思（主要是据说那个宝藏里面藏着一种美容水，喝了可以让这美丽的姐姐更加迷人），
于是她就竭尽全力想解决这个问题。BUT，她每次都以失败告终，因为这数字的个数是在太多了！于是她请天才的你帮他解决。
如果你帮她解决了这个问题，可是会得到很多甜头的哦！

【输入】
第一行一个整数 N 表示数字的个数，接下来一行为 N 个数。第三行读入一个 M，表示你看完那串数后需要被提问的次数，接下来 M 行，每行都有两个整数 A,B。

【输出】
输出共 M 行，每行输出一个数，表示对一个问题的回答。

数据范围与提示
对于 100\% 的数据，1 <=  N <= 2* 10^5,1 <=  M <= 10^4。

【输入样例】
6
34 1 8 123 3 2
4
1 2
1 5
3 4
2 3
【输出样例】
34
123
123
8
*/

const int N = 200010;
struct NODE {
	int l, r, max;
}tr[N*4];
int a[N];
int n, m;

void pushup(int u) {
	tr[u].max = max(tr[u << 1].max, tr[u << 1 | 1].max);
}

void build(int u, int l, int r) {
	tr[u] = { l,r ,a[l] };
	if (l == r) return;
	int mid = l + r >> 1;
	build(u << 1, l, mid); build(u << 1 | 1, mid + 1, r);
	pushup(u);
}

int query(int u, int l, int r) {
	if (tr[u].l >= l && tr[u].r <= r) return tr[u].max;   // 树中节点，已经被完全包含在[l, r]中了
	int mid = tr[u].l + tr[u].r >> 1;
	int v = -999999999;
	if (l <= mid) v = query(u << 1, l, r);
	if (r > mid) v = max(v, query(u << 1 | 1, l, r));
	return v;
}

int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}

	build(1, 1, n);

	cin >> m;
	for (int i = 0; i < m; i++) {
		int l,r;
		cin >> l >> r;
		cout << query(1, l, r) << endl;;
	}


	return 0;
}

